package com.itbaiazhan.myes2.templatetest;

import com.itbaiazhan.myes2.document.Product;
import org.elasticsearch.index.query.*;

import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
/*SpringDataElasticsearch提供了一个工具类ElasticsearchRestTemplate，
我们使用该类对象也能对ES进行操作。不用写接口，是直接操作 一般是操作文比效好，操作者索引不好*/
public class TemplateTest1 {

    @Autowired
    private ElasticsearchRestTemplate template;
    //创建索引，不建义使用，创建的索引没有结构
    @Test
    public void addIndex(){
        //获得索引操作对象
        IndexOperations indexOperations = template.indexOps(Product.class);
        //创建索引，无法设置索引结构
        indexOperations.create();
    }


    @Test
    public void delete(){
        IndexOperations indexOperations = template.indexOps(Product.class);
        indexOperations.delete();
    }

    //新增/修改文档  id不变，其它内容修改，就是修改文档
    @Test
    public void addDocument(){
        Product product = new Product(7,"es","es是一款很好的搜索引擎");
        template.save(product);
    }
    //删除文档
    @Test
    public void deleteDocument(){
       //template 删除是所有类型，所以要给定删除的实体类
        //ElasticsearchRepository 接口已指定了实体类
        template.delete("7",Product.class);
    }

    //查询文档
    @Test
    public void searchDocument(){
        //1确认查询方式
        //MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();
        //关键词方式
       // TermQueryBuilder builder = QueryBuilders.termQuery("productDesc","手机");
        //全文搜索  先分词后搜索
       MatchQueryBuilder builder = QueryBuilders.matchQuery("productDesc","我喜欢科幻小说");

        //2构建查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(builder).build();


        //3查询   参数1：查询的条件  参数2：查询的实体类
        SearchHits<Product> result = template.search(query, Product.class);

        //4处理查询结果
        for (SearchHit<Product> product : result) {
            //获取每一个对象
            Product content = product.getContent();
            System.out.println(content);
        }

    }
    //多条件查询
    @Test
    public void searchDocument2(){
        //1确认查询方式
        //模拟前端传进来的条件
        String productName = "elasticsearch";
        String productDesc = "优秀";
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        //如果没有传入参数，查询所有
        if(productName == null && productDesc == null){
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            builder.must(matchAllQueryBuilder);
        }else {
            if(productName != null && productName.length()>0){
                MatchQueryBuilder productName1 = QueryBuilders.matchQuery("productName", productName);
                builder.must(productName1);
            }
            if(productDesc != null && productDesc.length()>0){
                MatchQueryBuilder productDesc1 = QueryBuilders.matchQuery("productDesc", productDesc);
                builder.must(productDesc1);
            }
        }


        //2构建查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(builder).build();


        //3查询   参数1：查询的条件  参数2：查询的实体类
        SearchHits<Product> result = template.search(query, Product.class);

        //4处理查询结果
        for (SearchHit<Product> product : result) {
            //获取每一个对象
            Product content = product.getContent();
            System.out.println(content);
        }

    }

    //分页查询
    @Test
    public void searchDocumentPage(){
        //1确认查询方式
        MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();


        //2构建查询条件
        //分页条件
        Pageable pageable = PageRequest.of(0,3);
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .withPageable(pageable)
                .build();


        //3查询   参数1：查询的条件  参数2：查询的实体类
        SearchHits<Product> result = template.search(query, Product.class);

        //4处理查询结果
        List<Product> content = new ArrayList();
        for (SearchHit<Product> product : result) {
            //获取每一个对象
            Product product1 = product.getContent();
            content.add(product1);
        }

        /*封装Page对象，参数1：具体数据，参数2：分页条件对象，参数3：总条数*/
        Page<Product> page = new PageImpl<>(content,pageable,result.getTotalHits());
        System.out.println(page.getTotalElements());
        System.out.println(page.getTotalPages());
        System.out.println(page.getContent());
    }

    //结果排序
    @Test
    public void searchDocumentSort(){
        //1确认查询方式
        //排序条件  fieldSort("id")按哪个域排序   类型是SortBuild,不是FieldSortBuilder
        SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
        MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();

        //2构建查询条件
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .withSorts(sortBuilder)
                .build();


        //3查询   参数1：查询的条件  参数2：查询的实体类
        SearchHits<Product> result = template.search(query, Product.class);

        //4处理查询结果
        for (SearchHit<Product> product : result) {
            //获取每一个对象
            Product content = product.getContent();
            System.out.println(content);
        }

    }

}
